//
//  GJTakeVideoView.m
//  xmgjAppFront
//
//  Created by ZekiMini on 2020/9/16.
//  Copyright © 2020 guojutech. All rights reserved.
//

#import "GJTakeVideoView.h"

#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import "GJPhotoLibraryManager.h"
#import <Photos/Photos.h>
#import <CoreMotion/CoreMotion.h>


#define VIDEO_FILEPATH                                              @"video"

@interface GJTakeVideoView ()<AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAudioDataOutputSampleBufferDelegate, UIGestureRecognizerDelegate>
@property (nonatomic, strong) dispatch_queue_t videoQueue;

@property (strong, nonatomic) AVCaptureSession *captureSession;                          //负责输入和输出设备之间的数据传递

@property (nonatomic, strong) AVCaptureDeviceInput *videoInput;                          //视频输入
@property (nonatomic, strong) AVCaptureDeviceInput *audioInput;                          //声音输入

@property (nonatomic, strong) AVCaptureVideoDataOutput *videoOutput;
@property (nonatomic, strong) AVCaptureAudioDataOutput *audioOutput;

@property (strong, nonatomic) AVCaptureStillImageOutput *captureStillImageOutput;        //照片输出流

@property (nonatomic, strong) AVAssetWriter *assetWriter;
@property (nonatomic, strong) AVAssetWriterInput *assetWriterVideoInput;
@property (nonatomic, strong) AVAssetWriterInput *assetWriterAudioInput;
@property (nonatomic, strong) NSDictionary *videoCompressionSettings;
@property (nonatomic, strong) NSDictionary *audioCompressionSettings;
@property (nonatomic, assign) BOOL canWrite;

@property (strong, nonatomic) AVCaptureVideoPreviewLayer *captureVideoPreviewLayer;      //预览图层

@property (nonatomic, strong) NSTimer *timer;                                            //记录录制时间



@property (assign, nonatomic) Boolean isShooting;                                        //正在拍摄

@property (assign, nonatomic) UIDeviceOrientation shootingOrientation;                 //拍摄中的手机方向

@property (strong, nonatomic) NSURL *videoURL;                                           //视频文件地址

@end

@implementation GJTakeVideoView


- (instancetype)initWithFrame:(CGRect)frame
{
  self = [super initWithFrame:frame];
  if (self) {
    self.backgroundColor = [UIColor whiteColor];
  }
  return self;
}

#pragma mark  -- avcapturesession
/**
 *  开启会话
 */
- (void)startSession
{
  if (![self.captureSession isRunning])
  {
    [self.captureSession startRunning];
  }
}

/**
 *  停止会话
 */
- (void)stopSession
{
  if ([self.captureSession isRunning])
  {
    [self.captureSession stopRunning];
  }
}

#pragma mark -- initlization AVCapturesession 初始化视频采集
/**
 *  初始化AVCapture会话
 */
- (void)initAVCaptureSession
{
  //1、添加 "视频" 与 "音频" 输入流到session
  [self setupVideo];
  
  [self setupAudio];
  //
  //    //2、添加图片，movie输出流到session
  [self setupCaptureStillImageOutput];
  //
  //    //3、创建视频预览层，用于实时展示摄像头状态
  [self setupCaptureVideoPreviewLayer];
  
  //设置静音状态也可播放声音
  //    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
  //    [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
}


/**
 *  设置视频输入
 */
- (void)setupVideo
{
  AVCaptureDevice *captureDevice = [self getCameraDeviceWithPosition:AVCaptureDevicePositionFront];
  if (!captureDevice)
  {
    NSLog(@"取得前置摄像头时出现问题.");
    
    return;
  }
  
  NSError *error = nil;
  self.videoInput = [[AVCaptureDeviceInput alloc] initWithDevice:captureDevice error:&error];
  if (error)
  {
    NSLog(@"取得设备输入videoInput对象时出错，错误原因：%@", error);
    
    return;
  }
  
  //3、将设备输出添加到会话中
  if ([self.captureSession canAddInput:self.videoInput])
  {
    [self.captureSession addInput:self.videoInput];
    
  }
  
  self.videoOutput = [[AVCaptureVideoDataOutput alloc] init];
  self.videoOutput.alwaysDiscardsLateVideoFrames = YES; //立即丢弃旧帧，节省内存，默认YES
  [self.videoOutput setSampleBufferDelegate:self queue:self.videoQueue];
  if ([self.captureSession canAddOutput:self.videoOutput])
  {
    [self.captureSession addOutput:self.videoOutput];
  }
}
/**
 *  取得指定位置的摄像头
 *
 *  @param position 摄像头位置
 *
 *  @return 摄像头设备
 */
- (AVCaptureDevice *)getCameraDeviceWithPosition:(AVCaptureDevicePosition )position
{
  NSArray *cameras = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
  for (AVCaptureDevice *camera in cameras)
  {
    if ([camera position] == position)
    {
      return camera;
    }
  }
  return nil;
}
/**
 *  设置音频录入
 */
- (void)setupAudio
{
  NSError *error = nil;
  self.audioInput = [[AVCaptureDeviceInput alloc] initWithDevice:[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio] error:&error];
  if (error)
  {
    NSLog(@"取得设备输入audioInput对象时出错，错误原因：%@", error);
    
    return;
  }
  if ([self.captureSession canAddInput:self.audioInput])
  {
    [self.captureSession addInput:self.audioInput];
  }
  
  self.audioOutput = [[AVCaptureAudioDataOutput alloc] init];
  [self.audioOutput setSampleBufferDelegate:self queue:self.videoQueue];
  if([self.captureSession canAddOutput:self.audioOutput])
  {
    [self.captureSession addOutput:self.audioOutput];
  }
}
/**
 *  设置图片输出
 */
- (void)setupCaptureStillImageOutput
{
  self.captureStillImageOutput = [[AVCaptureStillImageOutput alloc] init];
  NSDictionary *outputSettings = @{
    //                                     AVVideoScalingModeKey:AVVideoScalingModeResizeAspect,
    AVVideoCodecKey:AVVideoCodecJPEG
  };
  [_captureStillImageOutput setOutputSettings:outputSettings];
  
  if ([self.captureSession canAddOutput:_captureStillImageOutput])
  {
    [self.captureSession addOutput:_captureStillImageOutput];
  }
}

/**
 *  设置预览layer
 */
- (void)setupCaptureVideoPreviewLayer
{
  
  [_captureVideoPreviewLayer removeFromSuperlayer];
  _captureVideoPreviewLayer = nil;
  _captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
  

  
  _captureVideoPreviewLayer.frame = self.bounds;
  _captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;           //填充模式
  
  [self.layer insertSublayer:_captureVideoPreviewLayer atIndex:0];
}



/**
 *  自动对焦自动曝光
 */
- (void)changeDeviceProperty
{
  AVCaptureDevice *captureDevice = [self.videoInput device];
  NSError *error;
  
  //注意改变设备属性前一定要首先调用lockForConfiguration:调用完之后使用unlockForConfiguration方法解锁
  if ([captureDevice lockForConfiguration:&error])
  {
    // 聚焦
    if ([captureDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus])
    {
      [captureDevice setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
    }
    
    // 曝光
    if ([captureDevice isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure])
    {
      [captureDevice setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
    }
    
    [captureDevice unlockForConfiguration];
  }
  else
  {
    NSLog(@"设置设备属性过程发生错误，错误信息：%@",error.localizedDescription);
  }
}

#pragma mark -- authorization 授权

/// 权限控制
- (void)initlizationAuthorization{
  AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
  if (authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied)
  {
    [self requestAuthorizationForVideo];
  }
  
  //判断用户是否允许访问麦克风权限
  authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
  if (authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied)
  {
    [self requestAuthorizationForVideo];
  }
}

/**
 *  请求权限
 */
- (void)requestAuthorizationForVideo
{
  // 请求相机权限
  AVAuthorizationStatus videoAuthStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
  if (videoAuthStatus != AVAuthorizationStatusAuthorized)
  {
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
    
    NSString *appName = [infoDictionary objectForKey:@"CFBundleDisplayName"];
    if (appName == nil)
    {
      appName = @"APP";
    }
    NSString *message = [NSString stringWithFormat:@"允许%@访问你的相机？", appName];
    
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"警告" message:message preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
      //            [weakSelf dismissViewControllerAnimated:YES completion:nil];
    }];
    
    UIAlertAction *setAction = [UIAlertAction actionWithTitle:@"设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
      NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
      if ([[UIApplication sharedApplication] canOpenURL:url])
      {
        [[UIApplication sharedApplication] openURL:url];
      }
      //            [weakSelf dismissViewControllerAnimated:YES completion:nil];
    }];
    
    [alertController addAction:okAction];
    [alertController addAction:setAction];
    
    [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
  }
  
  // 请求麦克风权限
  AVAuthorizationStatus audioAuthStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
  if (audioAuthStatus != AVAuthorizationStatusAuthorized)
  {
    NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
    
    NSString *appName = [infoDictionary objectForKey:@"CFBundleDisplayName"];
    if (appName == nil)
    {
      appName = @"APP";
    }
    NSString *message = [NSString stringWithFormat:@"允许%@访问你的麦克风？", appName];
    
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"警告" message:message preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
      //            [weakSelf dismissViewControllerAnimated:YES completion:nil];
    }];
    
    UIAlertAction *setAction = [UIAlertAction actionWithTitle:@"设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
      NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
      if ([[UIApplication sharedApplication] canOpenURL:url])
      {
        [[UIApplication sharedApplication] openURL:url];
      }
      //            [weakSelf dismissViewControllerAnimated:YES completion:nil];
    }];
    
    [alertController addAction:okAction];
    [alertController addAction:setAction];
    
    //        [self presentViewController:alertController animated:YES completion:nil];
  }
  
  
}

- (void)requestAuthorizationForPhotoLibrary
{
  // 请求照片权限
  [GJPhotoLibraryManager requestALAssetsLibraryAuthorizationWithCompletion:^(Boolean isAuth) {
    
    if (!isAuth)
    {
      NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
      
      NSString *appName = [infoDictionary objectForKey:@"CFBundleDisplayName"];
      if (appName == nil)
      {
        appName = @"APP";
      }
      NSString *message = [NSString stringWithFormat:@"允许%@访问你的相册？", appName];
      
      UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"警告" message:message preferredStyle:UIAlertControllerStyleAlert];
      
      UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        //                [weakSelf dismissViewControllerAnimated:YES completion:nil];
      }];
      
      UIAlertAction *setAction = [UIAlertAction actionWithTitle:@"设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        if ([[UIApplication sharedApplication] canOpenURL:url])
        {
          [[UIApplication sharedApplication] openURL:url];
        }
        //                [weakSelf dismissViewControllerAnimated:YES completion:nil];
      }];
      
      [alertController addAction:okAction];
      [alertController addAction:setAction];
      
      [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
      
    }
  }];
}
#pragma mark - 视频录制


/**
 *  开始录制视频
 */
- (void)startVideoRecorder
{
  
  NSURL *url = [NSURL fileURLWithPath:[self createVideoFilePath]];
  self.videoURL = url;
  
  [self setUpWriter];
  _isShooting = YES;
  //    __weak typeof(self) weakSelf = self;
  //    dispatch_async(dispatch_get_main_queue(), ^{
  //
  //    });
}

/**
 *  结束录制视频
 */
- (void)stopVideoRecorder
{
  if (_isShooting)
  {
    _isShooting = NO;
    
    
    __weak __typeof(self)weakSelf = self;
    if(_assetWriter && _assetWriter.status == AVAssetWriterStatusWriting)
    {
      //            dispatch_async(self.videoQueue, ^{
      [_assetWriter finishWritingWithCompletionHandler:^{
        weakSelf.canWrite = NO;
        weakSelf.assetWriter = nil;
        weakSelf.assetWriterAudioInput = nil;
        weakSelf.assetWriterVideoInput = nil;
        [GJUtil sendNotificationForRNEventEmitterWithActionKey:@"RECORD_FILE_RESULT" parameter:@{@"path":[self.videoURL absoluteString]}];
      }];
      //            });
    }
  }
  else
  {
    // nothing
  }
}

/**
 *  设置写入视频属性
 */
- (void)setUpWriter
{
  if (self.videoURL == nil)
  {
    return;
  }
  
  self.assetWriter = [AVAssetWriter assetWriterWithURL:self.videoURL fileType:AVFileTypeMPEG4 error:nil];
  //写入视频大小
  NSInteger numPixels = kScreenWidth * kScreenHeight;
  
  //每像素比特
  CGFloat bitsPerPixel = 6.0;
  NSInteger bitsPerSecond = numPixels * bitsPerPixel;
  
  // 码率和帧率设置
  NSDictionary *compressionProperties = @{ AVVideoAverageBitRateKey : @(bitsPerSecond),
                                           AVVideoExpectedSourceFrameRateKey : @(15),
                                           AVVideoMaxKeyFrameIntervalKey : @(15),
                                           AVVideoProfileLevelKey : AVVideoProfileLevelH264BaselineAutoLevel };
  CGFloat width = kScreenHeight;
  CGFloat height = kScreenWidth;
  if (isIphoneX)
  {
    width = kScreenHeight - 146;
    height = kScreenWidth;
  }
  //视频属性
  self.videoCompressionSettings = @{ AVVideoCodecKey : AVVideoCodecH264,
                                     AVVideoWidthKey : @(width * 2),
                                     AVVideoHeightKey : @(height * 2),
                                     AVVideoScalingModeKey : AVVideoScalingModeResizeAspectFill,
                                     AVVideoCompressionPropertiesKey : compressionProperties };
  
  _assetWriterVideoInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:self.videoCompressionSettings];
  //expectsMediaDataInRealTime 必须设为yes，需要从capture session 实时获取数据
  _assetWriterVideoInput.expectsMediaDataInRealTime = YES;
  
  if (self.shootingOrientation == UIDeviceOrientationLandscapeRight)
  {
    _assetWriterVideoInput.transform = CGAffineTransformMakeRotation(M_PI);
  }
  else if (self.shootingOrientation == UIDeviceOrientationLandscapeLeft)
  {
    _assetWriterVideoInput.transform = CGAffineTransformMakeRotation(0);
  }
  else if (self.shootingOrientation == UIDeviceOrientationPortraitUpsideDown)
  {
    _assetWriterVideoInput.transform = CGAffineTransformMakeRotation(M_PI + (M_PI / 2.0));
  }
  else
  {
    _assetWriterVideoInput.transform = CGAffineTransformMakeRotation(M_PI / 2.0);
  }
  
  // 音频设置
  self.audioCompressionSettings = @{ AVEncoderBitRatePerChannelKey : @(28000),
                                     AVFormatIDKey : @(kAudioFormatMPEG4AAC),
                                     AVNumberOfChannelsKey : @(1),
                                     AVSampleRateKey : @(22050) };
  
  _assetWriterAudioInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:self.audioCompressionSettings];
  _assetWriterAudioInput.expectsMediaDataInRealTime = YES;
  
  if ([_assetWriter canAddInput:_assetWriterVideoInput])
  {
    [_assetWriter addInput:_assetWriterVideoInput];
  }
  else
  {
    NSLog(@"AssetWriter videoInput append Failed");
  }
  
  if ([_assetWriter canAddInput:_assetWriterAudioInput])
  {
    [_assetWriter addInput:_assetWriterAudioInput];
  }
  else
  {
    NSLog(@"AssetWriter audioInput Append Failed");
  }
  
  _canWrite = NO;
}

- (NSString *)createVideoFilePath
{
  // 创建视频文件的存储路径
  NSString *filePath = [self createVideoFolderPath];
  if (filePath == nil)
  {
    return nil;
  }
  
  NSString *videoType = @".mp4";
  NSString *videoDestDateString = [self createFileNamePrefix];
  NSString *videoFileName = [videoDestDateString stringByAppendingString:videoType];
  
  NSUInteger idx = 1;
  /*We only allow 10000 same file name*/
  NSString *finalPath = [NSString stringWithFormat:@"%@/%@", filePath, videoFileName];
  
  while (idx % 10000 && [[NSFileManager defaultManager] fileExistsAtPath:finalPath])
  {
    finalPath = [NSString stringWithFormat:@"%@/%@_(%lu)%@", filePath, videoDestDateString, (unsigned long)idx++, videoType];
  }
  
  return finalPath;
}

- (NSString *)createVideoFolderPath
{
  NSFileManager *fileManager = [NSFileManager defaultManager];
  NSString *homePath = NSHomeDirectory();
  
  NSString *tmpFilePath;
  
  if (homePath.length > 0)
  {
    NSString *documentPath = [homePath stringByAppendingString:@"/Documents"];
    if ([fileManager fileExistsAtPath:documentPath isDirectory:NULL] == YES)
    {
      BOOL success = NO;
      
      NSArray *paths = [fileManager contentsOfDirectoryAtPath:documentPath error:nil];
      
      //offline file folder
      tmpFilePath = [documentPath stringByAppendingString:[NSString stringWithFormat:@"/%@", VIDEO_FILEPATH]];
      if ([paths containsObject:VIDEO_FILEPATH] == NO)
      {
        success = [fileManager createDirectoryAtPath:tmpFilePath withIntermediateDirectories:YES attributes:nil error:nil];
        if (!success)
        {
          tmpFilePath = nil;
        }
      }
      return tmpFilePath;
    }
  }
  
  return false;
}

/**
 *  创建文件名
 */
- (NSString *)createFileNamePrefix
{
  NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
  [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss zzz"];
  
  NSString *destDateString = [dateFormatter stringFromDate:[NSDate date]];
  destDateString = [destDateString stringByReplacingOccurrencesOfString:@" " withString:@"-"];
  destDateString = [destDateString stringByReplacingOccurrencesOfString:@"+" withString:@"-"];
  destDateString = [destDateString stringByReplacingOccurrencesOfString:@":" withString:@"-"];
  
  return @"xmgj";
}


#pragma mark - AVCaptureVideoDataOutputSampleBufferDelegate AVCaptureAudioDataOutputSampleBufferDelegate

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
  @autoreleasepool
  {
    //视频
    if (connection == [self.videoOutput connectionWithMediaType:AVMediaTypeVideo])
    {
      @synchronized(self)
      {
        if (_isShooting)
        {
          [self appendSampleBuffer:sampleBuffer ofMediaType:AVMediaTypeVideo];
        }
      }
    }
    
    //音频
    if (connection == [self.audioOutput connectionWithMediaType:AVMediaTypeAudio])
    {
      @synchronized(self)
      {
        if (_isShooting)
        {
          [self appendSampleBuffer:sampleBuffer ofMediaType:AVMediaTypeAudio];
        }
      }
    }
  }
}


/**
 *  开始写入数据
 */
- (void)appendSampleBuffer:(CMSampleBufferRef)sampleBuffer ofMediaType:(NSString *)mediaType
{
  if (sampleBuffer == NULL)
  {
    NSLog(@"empty sampleBuffer");
    return;
  }
  
  //    CFRetain(sampleBuffer);
  //    dispatch_async(self.videoQueue, ^{
  @autoreleasepool
  {
    if (!self.canWrite && mediaType == AVMediaTypeVideo)
    {
      [self.assetWriter startWriting];
      [self.assetWriter startSessionAtSourceTime:CMSampleBufferGetPresentationTimeStamp(sampleBuffer)];
      self.canWrite = YES;
    }
    
    //写入视频数据
    if (mediaType == AVMediaTypeVideo)
    {
      if (self.assetWriterVideoInput.readyForMoreMediaData)
      {
        BOOL success = [self.assetWriterVideoInput appendSampleBuffer:sampleBuffer];
        if (!success)
        {
          @synchronized (self)
          {
            [self stopVideoRecorder];
          }
        }
      }
    }
    
    //写入音频数据
    if (mediaType == AVMediaTypeAudio)
    {
      if (self.assetWriterAudioInput.readyForMoreMediaData)
      {
        BOOL success = [self.assetWriterAudioInput appendSampleBuffer:sampleBuffer];
        if (!success)
        {
          @synchronized (self)
          {
            [self stopVideoRecorder];
          }
        }
      }
    }
    //            CFRelease(sampleBuffer);
  }
  //    });
}


#pragma mark - 懒加载
- (AVCaptureSession *)captureSession
{
  if (_captureSession == nil)
  {
    _captureSession = [[AVCaptureSession alloc] init];
    
    if ([_captureSession canSetSessionPreset:AVCaptureSessionPresetHigh])
    {
      _captureSession.sessionPreset = AVCaptureSessionPresetHigh;
    }
  }
  
  return _captureSession;
}

- (dispatch_queue_t)videoQueue
{
  if (!_videoQueue)
  {
    _videoQueue = dispatch_queue_create("GJTakeVideoView", DISPATCH_QUEUE_SERIAL); // dispatch_get_main_queue();
  }
  
  return _videoQueue;
}



#pragma mark -- RN && Method
- (void)takeVideo{
  [self startVideoRecorder];
}
- (void)startCamera{
  [self initlizationAuthorization];
  [self initAVCaptureSession];
  [self startSession];
  [self changeDeviceProperty];
}
- (void)stopTakeVideo{
  [self stopVideoRecorder];
}

- (void)closeCamera{
  [self.captureSession removeInput:self.videoInput];
  [self.captureSession removeOutput:self.videoOutput];
  [self.captureVideoPreviewLayer removeFromSuperlayer];
  [self stopSession];
}
@end


